#include "Color.h"
#include "Containers/Map.h"
#include <cassert>

SColor SColor::None=SColor(0,0,0,0);
SColor SColor::Black=SColor(0,0,0,1);
SColor SColor::Green=SColor(0,1,0,1);
SColor SColor::HalfGreen=SColor::FromHexRGB(0x007F00);
SColor SColor::Red=SColor(1,0,0,1);
SColor SColor::Blue=SColor(0,0,1,1);
SColor SColor::Yellow=SColor(1,1,0,1);
SColor SColor::White=SColor(1,1,1,1);


SColor SColor::FromHexRGB(uint32_t InHexRGB )
{
    assert(InHexRGB <= 0xFFFFFF && "cant adreess Alpha channel");

    uint32_t R=InHexRGB>>16;
    uint32_t G=(InHexRGB & 0xFF00)>>8;
    uint32_t B=InHexRGB & 0xFF;

    return SColor(R/255.0f,G/255.0f,B/255.0f,1);
}

CString SColor::ToHexString() const
{
    uint32_t _R=static_cast<uint32_t>(this->R*255);
    uint32_t _G=static_cast<uint32_t>(this->G*255);
    uint32_t _B=static_cast<uint32_t>(this->B*255);
    uint32_t _A=static_cast<uint32_t>(this->A*255);

    return U"#"+CString::CreateHex(_R)+CString::CreateHex(_G)+CString::CreateHex(_B)+CString::CreateHex(_A);
}

SColor SColor::operator* (float Factor) const
{
    return SColor(R*Factor,G*Factor,B*Factor,A*Factor);
}

SColor SColor::operator+(const SColor &Other) const
{
    return SColor(R+Other.R,G+Other.G,B+Other.B,A+Other.A);
}

SColor SColor::operator+=(const SColor &Other)
{
    R+=Other.R;
    G+=Other.G;
    B+=Other.B;
    A+=Other.A;

    return *this;
}

SColor SColor::operator-(const SColor & Other) const
{
    return SColor(R-Other.R,G-Other.G,B-Other.B,A-Other.A);
}

SColor SColor::operator-=(const SColor &Other)
{
    R-=Other.R;
    G-=Other.G;
    B-=Other.B;
    A-=Other.A;

    return *this;
}

uint64_t SColor::GetHashCode() const
{
    return 
    WH::HashCombine(std::hash<float>()(A), WH::HashCombine(std::hash<float>()(B), WH::HashCombine(std::hash<float>()(R), std::hash<float>()(G))));
}

void SColor::ToFloatArray(float OutArray[4]) const
{
    OutArray[0] = R;
    OutArray[1] = G;
    OutArray[2] = B;
    OutArray[3] = A;
}
